// Application of class
// Created by Administrator on 2025/6/11.
//

#include <iostream>
using namespace std;

/**
 * student class
 */
class Student {
public:
    unsigned long int id;
    string name;
    unsigned short int age;
    unsigned short int sex;
    string address;

    // constructor

    Student(long int id, string name, short int age, short int sex, string address): id(id), name(name), age(age),
        sex(sex), address(address) {
        cout << "created params constructor" << endl;
    }

    Student() {
        cout << "created not params constructor" << endl;
    };

    // destroy

    ~Student() {
        cout << "object are destroy" << endl;
    };

    // statement member function

    void set(unsigned long int id, string name, unsigned short int age, unsigned short int sex, string address);

    string getInfo();
};

// member function
void Student::set(unsigned long int id, string name, unsigned short int age, unsigned short int sex, string address) {
    this->id = id;
    this->name = name;
    this->age = age;
    this->sex = sex;
    this->address = address;
}

string Student::getInfo() {
    return "\tid=" + to_string(id) + "\tname=" + name + "\tage=" + to_string(age) + "\tsex=" + to_string(sex) +
           "\taddress=" + address;
}

// int main(int argc, char *argv[]) {
//     Student student;
//     student.set(1, "张三", 18, 1, "北京");
//     string info = student.getInfo();
//     cout << "student info is :" << info << endl;
//
//     Student student2(2, "李四", 20, 0, "上海");
//     string info2 = student2.getInfo();
//     cout << "student2 info is :" << info2 << endl;
// }


/**
 * Copy constructor
 * 当前对象被赋值给新的对象时，会调用拷贝构造函数
 * 1、参数值传递
 * 2、对象值传递
 * 3、返回对象值
 */
class Line {
public:
    int getLength(void);

    Line(int len); // simple constructor
    Line(const Line &obj); // copy constructor
    ~Line(); // destructor

private:
    int *ptr;
};

Line::Line(int len) {
    cout << "call constructor" << endl;
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line &obj) {
    cout << "call copy constructor" << endl;
    ptr = new int;
    *ptr = *obj.ptr; // copy value
}

Line::~Line() {
    cout << "release memory" << endl;
    delete ptr;
}

int Line::getLength(void) {
    return *ptr;
}

// call copy constructor
void display(Line obj) {
    cout << "length of len is:" << obj.getLength() << endl;
}


// int main(int argc, char *argv[]) {
//     Line line(10);
//     display(line); // call 1
//     Line line2 = line; // call 2
//     display(line2); // call 3
// }

/**
 * 友元函数
 * 友元是定义在类的外部，有权访问类的所有变量（无视访问修饰符）
 *
 * friend function
 */
class Box {
    double width;

public:
    double height;

    friend void printWidth(Box box);

    friend class BigBox;

    void setWidth(double wid);
};

void Box::setWidth(double wid) {
    width = wid;
}

// 不是成员函数，所以不能用this指针
void printWidth(Box box) {
    // 因为 printWidth 是 Box 的友元函数，它可以直接访问任何 Box 的所有成员（包括private）
    cout << "width is :" << box.width << endl;
}

class BigBox {
public:
    void setBoxWidth(double width, Box &box) {
        // 因为 BigBox 是 Box 的友元类，所以它可以直接访问  Box 的所有成员（包括private）
        box.width = width;
    }
};

// int main(int argc, char *argv[]) {
//     Box box;
//     box.setWidth(10.0);
//     box.height = 55.0;
//     printWidth(box);
//
//     BigBox bigBox;
//     bigBox.setBoxWidth(666.0, box);
//     printWidth(box);
// }

/**
 * inline
 * 内联函数
 *
 * 适用于简单的函数，10行代码以内。
 * 编译器会将内联函数的代码复制到调用它的地方，从而提高性能，而不是像普通函数一样调用。
 * 类里面定义的函数默认为内联函数
 *
 * 空间换时间
 */

/**
 * 计算最大值
 *
 * @param num1
 * @param num2
 * @return
 */
inline int max(int num1, int num2) {
    return num1 > num2 ? num1 : num2;
}

class Order {
    signed long int id;
    signed long int createTime;

public:
    Order(long int id, long int createTime): id(id), createTime(createTime) {
    }

    // default is inline function
    signed long int getId() {
        return id;
    }

    signed long int getCreateTime() {
        return createTime;
    }
};

// int main(int argc, char *argv[]) {
//     int n1 = 10;
//     int n2 = 20;
//     int maxNum = max(n1, n2); // 直接编译为：int maxNum = n1 > n2 ? n1 : n2;
//     cout << "max value is:" << maxNum << endl;
//
//     // 类中的函数默认是inline的
//     Order order(10001, 1749634358);
//     cout << "order id:" << order.getId() << " create time:" << order.getCreateTime() << endl;
// }

/**
 * C++ this 指针
 *
 * this 指向当前对象的实例
 * this 是一个隐藏的指针，在类的成员函数中使用，用来指向调用对象
 * 当对象的成员函数被调用时，编译器会隐式地传递该对象的地址作为 this 指针
 * 友元函数没有 this 指针，只有成员函数/属性才会有指针
 */

class MyClass {
    int value;

public :
    void setValue(int value) {
        // 用 this 指向成员 value 属性，不然这里获取的是局部 value
        this->value = value;
    }

    void ptint() {
        cout << "value is:" << this->value << endl;
    }
};


class House {
    int length;
    int width;
    int height;

public:
    House(int length = 2.0, int width = 2.0, int height = 2.0): length(length), width(width), height(height) { ; }

    double volume() const {
        return length * width * height;
    }

    bool compare(House house) {
        // 获取当前实例的 volume 和传进来的 volume 进行比较
        return this->volume() > house.volume();
    }
};

// int main(int argc, char *argv[]) {
//     MyClass myClass;
//     myClass.setValue(111);
//     myClass.ptint();
//
//     House house1(10, 10, 10);
//     House house2(12, 12, 12);
//
//     bool isGt = house2.compare(house1);
//     cout << "house1 is gt house2 ? " << isGt << endl;
// }


/**
 * 指向类的指针
 *
 */

class ObjClass {
public:
    int value;

    void print() const {
        cout << "value is :" << value << endl;
    }
};

void ptrParamFunc(ObjClass *obj) {
    obj->print();
}

// int main(int argc, char *argv[]) {
//     ObjClass objClass;
//     objClass.value = 66;
//     objClass.print();
//
//     ObjClass *objClassPtr = &objClass;
//     objClassPtr->print();
//     cout << "value :" << objClassPtr->value << endl;
//
//     // 动态分配内存创建对象
//     ObjClass *ptr = new ObjClass;
//     ptr->value = 666;
//     ptr->print();
//
//     // 指针作为参数
//     ptr->value = 555;
//     ptrParamFunc(ptr);
//
//     // 释放动态分配的内存
//     delete ptr;
// }


/**
 * C++ 静态
 *
 * 使用static将成员定义为静态的，无论创建多少个对象静态成员都只有一个副本
 * 静态成员在所以对象中是共享的
 *
 */

class Post {
    long id;
    string title;
    long createTime;

public:
    // statement static variable
    static int objectCount;

    Post(long id, string title, long createTime) {
        cout << "create constructor " << endl;
        this->id = id;
        this->title = title;
        this->createTime = createTime;
        // each time create a object, objectCount will increase 1
        objectCount++;
    }

    // static function
    static int getObjCount() {
        return objectCount;
    }
};

// impl static variable
int Post::objectCount = 0;

// int main(int argc, char *argv[]) {
//     Post post1(1, "C++ start!", 1234567890);
//     Post post2(2, "Java Learn", 1234567855);
//
//     cout << "object count: " << Post::objectCount << endl;
//     cout << "object count: " << Post::getObjCount() << endl;
// }
